#include "cbinary.h"

/**
 * writeChar - writes char into binary file
 * @param fh
 * @param num
 * @return num of written bytes
 */
unsigned int CBinary::writeChar(ostream &fh, const char &num) {
  return fh.rdbuf()->sputn((char*) &num, sizeof(num));
}
//---------------------------------------------------------------------------

/**
 * writeShort - writes short integer into binary file
 * @param fh
 * @param num
 * @return num of written bytes
 */
unsigned int CBinary::writeShort(ostream &fh, const short &num) {
  return fh.rdbuf()->sputn((char*) &num, sizeof(num));
}
//---------------------------------------------------------------------------

/**
 * writeInt - writes integer into binary file
 * @param fh
 * @param num
 * @return num of written bytes
 */
unsigned int CBinary::writeInt(ostream &fh, const int &num) {
  return fh.rdbuf()->sputn((char*) &num, sizeof(num));
}
//---------------------------------------------------------------------------

/**
 * writeUChar - writes unsigned char into binary file
 * @param fh
 * @param num
 * @return num of written bytes
 */
unsigned int CBinary::writeUChar(ostream &fh, const unsigned char &num) {
  return fh.rdbuf()->sputn((char*) &num, sizeof(num));
}
//---------------------------------------------------------------------------

/**
 * writeUShort - writes unsigned short integer into binary file
 * @param fh
 * @param num
 * @return num of written bytes
 */
unsigned int CBinary::writeUShort(ostream &fh, const unsigned short &num) {
  return fh.rdbuf()->sputn((char*) &num, sizeof(num));
}
//---------------------------------------------------------------------------

/**
 * writeUInt - writes unsigned integer into binary file
 * @param fh
 * @param num
 * @return num of written bytes
 */
unsigned int CBinary::writeUInt(ostream &fh, const unsigned int &num) {
  return fh.rdbuf()->sputn((char*) &num, sizeof(num));
}
//---------------------------------------------------------------------------

/**
 * writeFloat - writes float into binary file
 * @param fh
 * @param num
 * @return num of written bytes
 */
unsigned int CBinary::writeFloat(ostream &fh, const float &num) {
  return fh.rdbuf()->sputn((char*) &num, sizeof(num));
}
//---------------------------------------------------------------------------

/**
 * writeDouble - writes double into binary file
 * @param fh
 * @param num
 * @return num of written bytes
 */
unsigned int CBinary::writeDouble(ostream &fh, const double &num) {
  return fh.rdbuf()->sputn((char*) &num, sizeof(num));
}
//---------------------------------------------------------------------------

/**
 * writeString - writes string into binary file
 * @param fh
 * @param str
 * @return num of written bytes
 */
unsigned int CBinary::writeString(ostream &fh, const string &str) {
  return writeInt(fh, str.length()) +
         fh.rdbuf()->sputn(str.c_str(), str.length());
}
//---------------------------------------------------------------------------

/**
 * writeTIndex - writes TIndex into binary file
 * @param fh
 * @param num
 * @return num of written bytes
 */
unsigned int CBinary::writeTIndex(ostream &fh, const TIndex &num) {
  return fh.rdbuf()->sputn((char*) &num, sizeof(num));
}
//---------------------------------------------------------------------------

/**
 * writeBool - writes boolean into binary file
 * @param fh
 * @param val
 * @return num of written bytes
 */
unsigned int CBinary::writeBool(ostream &fh, const bool &val) {
  return fh.rdbuf()->sputn((char*) &val, sizeof(val));
}
//---------------------------------------------------------------------------

/**
 * writeCColor - writes CColor into binary file
 * @param fh
 * @param c
 * @return num of written bytes
 */
unsigned int CBinary::writeCColor(ostream &fh, const CColor &c) {
  return writeUChar(fh, c.getR()) + writeUChar(fh, c.getG()) +
         writeUChar(fh, c.getB());
}
//---------------------------------------------------------------------------

/**
 * writeBuffer - writes buffer into file
 * @param fh
 * @param buf
 * @param s
 * @return num of written bytes
 */
unsigned int CBinary::writeBuffer(ostream &fh, const char* buf,
                                  unsigned int s) {
  return fh.rdbuf()->sputn(buf, s);
}
//---------------------------------------------------------------------------

/**
 * readChar - reads char from binary file
 * @param fh
 * @param num
 * @return num of read bytes
 */
unsigned int CBinary::readChar(istream &fh, char &num) {
  fh.read((char*) &num, sizeof(char));
  return fh.gcount();
}
//---------------------------------------------------------------------------

/**
 * readShort - reads short integer from binary file
 * @param fh
 * @param num
 * @return num of read bytes
 */
unsigned int CBinary::readShort(istream &fh, short &num) {
  fh.read((char*) &num, sizeof(short));
  return fh.gcount();
}
//---------------------------------------------------------------------------

/**
 * readInt - reads integer from binary file
 * @param fh
 * @param num
 * @return num of read bytes
 */
unsigned int CBinary::readInt(istream &fh, int &num) {
  fh.read((char*) &num, sizeof(int));
  return fh.gcount();
}
//---------------------------------------------------------------------------

/**
 * readUChar - reads unsigned char from binary file
 * @param fh
 * @param num
 * @return num of read bytes
 */
unsigned int CBinary::readUChar(istream &fh, unsigned char &num) {
  fh.read((char*) &num, sizeof(unsigned char));
  return fh.gcount();
}
//---------------------------------------------------------------------------

/**
 * readUShort - reads unsigned short integer from binary file
 * @param fh
 * @param num
 * @return num of read bytes
 */
unsigned int CBinary::readUShort(istream &fh, unsigned short &num) {
  fh.read((char*) &num, sizeof(unsigned short));
  return fh.gcount();
}
//---------------------------------------------------------------------------

/**
 * readUInt - reads unsigned integer from binary file
 * @param fh
 * @param num
 * @return num of read bytes
 */
unsigned int CBinary::readUInt(istream &fh, unsigned int &num) {
  fh.read((char*) &num, sizeof(unsigned int));
  return fh.gcount();
}
//---------------------------------------------------------------------------

/**
 * readFloat - reads float from binary file
 * @param fh
 * @param num
 * @return num of read bytes
 */
unsigned int CBinary::readFloat(istream &fh, float &num) {
  fh.read((char*) &num, sizeof(float));
  return fh.gcount();
}
//---------------------------------------------------------------------------

/**
 * readDouble - reads double from binary file
 * @param fh
 * @param num
 * @return num of read bytes
 */
unsigned int CBinary::readDouble(istream &fh, double &num) {
  fh.read((char*) &num, sizeof(double));
  return fh.gcount();
}
//---------------------------------------------------------------------------

/**
 * readBool - reads boolean from binary file
 * @param fh
 * @param val
 * @return num of read bytes
 */
unsigned int CBinary::readBool(istream &fh, bool &val) {
  fh.read((char*) &val, sizeof(bool));
  return fh.gcount();
}
//---------------------------------------------------------------------------

/**
 * readTIndex - reads TIndex from binary file
 * @param fh
 * @param val
 * @return num of read bytes
 */
unsigned int CBinary::readTIndex(istream &fh, TIndex &num) {
  fh.read((char*) &num, sizeof(TIndex));
  return fh.gcount();
}
//---------------------------------------------------------------------------

/**
 * readString - reads string from binary file
 * @param fh
 * @param str
 * @return num of read bytes
 */
unsigned int CBinary::readString(istream &fh, string &str) {
  int length, bytesRead(readInt(fh, length));
  if (length != 0) {
    char* pstr = new(nothrow) char[length + 1];
    fh.read(pstr, length);
    pstr[length] = '\0';
    str = pstr;
  }
  return bytesRead + sizeof(char) * length;
}
//---------------------------------------------------------------------------

/**
 * readPChar - reads string, saved as PCHAR, from binary file
 * @param fh
 * @param str
 * @return num of read bytes
 */
unsigned int CBinary::readPChar(istream &fh, string &str) {
  int index(0);
  char* buffer = {0};
  fh.read(buffer, sizeof(char));
  while (*(buffer + index++) != 0) fh.read(buffer + index, sizeof(char));
  str = string(buffer);
  return sizeof(char) * (strlen(buffer) + 1);
}
//---------------------------------------------------------------------------

/**
 * readCColor - reads CColor from binary file
 * @param fh
 * @param c
 * @return num of read bytes
 */
unsigned int CBinary::readCColor(istream &fh, CColor &c) {
  unsigned char r(0), g(0), b(0);
  int bytesRead(readUChar(fh, r) + readUChar(fh, g) + readUChar(fh, b));
  c = CColor(r, g, b);
  return bytesRead;
}
//---------------------------------------------------------------------------

/**
 * readBuffer - reads buffer from binary file
 * @param fh
 * @param buf
 * @param s
 * @return num of read bytes
 */
unsigned int CBinary::readBuffer(istream &fh, char* buf, unsigned int s) {
  fh.read(buf, s);
  return fh.gcount();
}
//---------------------------------------------------------------------------
